package io.gitee.tuo_tuo.jfinaldevassistance.model;

import com.alibaba.fastjson.JSONObject;
import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.IAtom;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import io.gitee.tuo_tuo.jfinaldevassistance.Result;
import io.gitee.tuo_tuo.jfinaldevassistance.model.base.BaseWorkflowModel;
import org.apache.commons.lang3.StringUtils;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * Generated by JFinal.
 */
@SuppressWarnings("serial")
public class WorkflowModel extends BaseWorkflowModel<WorkflowModel> {
	private static final Log log = Log.getLog(WorkflowModel.class);
	public static final WorkflowModel dao = new WorkflowModel().dao();

	List<WorknodeModel> worknodeModelList = new ArrayList<>();
	List<WorknodeLinkModel> worknodeLinkModelList = new ArrayList<>();
	List<WorknodeExecuteFormModel> worknodeExecuteFormModelList = new ArrayList<>();

	/**
	 * 工作流解析
	 * @return
	 */
	public Result parse(){
		Result result;
		String flowChart = getFlowChart();
		if(StringUtils.isBlank(flowChart)){
			return new Result(false, "没有找到流程图");
		}
		JSONObject flowChartJson = JSONObject.parseObject(flowChart);

		log.info("解析工作节点模型 ...");
		if(flowChartJson.containsKey("nodes")){
			JSONObject nodes = flowChartJson.getJSONObject("nodes");
			result = parseWorkflowNodes(nodes);
			if(result.getCode() < 0){
				return result;
			}
		}else {
			return new Result(false, "没有找到工作节点模型");
		}

		log.info("解析节点连线模型 ...");
		if(flowChartJson.containsKey("lines")){
			JSONObject lines = flowChartJson.getJSONObject("lines");
			result = parseWorkflowLines(lines);
			if(result.getCode() < 0){
				return result;
			}
		}else {
			return new Result(false, "没有找到节点连线模型");
		}

		if(flowChartJson.containsKey("extras")){
			log.info("解析节点执行表单 ...");
			JSONObject extras = flowChartJson.getJSONObject("extras");
			result = parseWorkflowExtras(extras);
			if(result.getCode() < 0){
				return result;
			}
		}
		return new Result(true, "流程解析成功");
	}

	/**
	 * 工作流保存
	 * @return
	 */
	public Result persistence(){
		boolean success = Db.tx(new IAtom(){
			@Override
			public boolean run() throws SQLException {
				if(save() == false){
					return false;
				}
				Integer workflowId = getId();
				for(WorknodeModel worknodeModel : worknodeModelList){
					worknodeModel.setWorkflowModelId(workflowId);
				}
				int[] ints1 = Db.batchSave(worknodeModelList, worknodeModelList.size());
				worknodeModelList = WorknodeModel.dao.findByWorkFlowModelId(workflowId);
				for (WorknodeLinkModel worknodeLinkModel : worknodeLinkModelList){
					WorknodeModel startNodeModel = worknodeLinkModel.getStartNodeModel();
					WorknodeModel endNodeModel = worknodeLinkModel.getEndNodeModel();
					worknodeLinkModel.setWorknodeModelId(serarch(startNodeModel.getNodeKey()).getId());
					worknodeLinkModel.setNextModelId(serarch(endNodeModel.getNodeKey()).getId());
				}
				int[] ints2 = Db.batchSave(worknodeLinkModelList, worknodeLinkModelList.size());
				int[] ints3 = Db.batchSave(worknodeExecuteFormModelList, worknodeExecuteFormModelList.size());
				return checkBatchResult(ints1) && checkBatchResult(ints2) && checkBatchResult(ints3);
			}
		});
		return new Result(success, success ? "流程保存成功" : "流程保存失败");
	}

	public Page<Record> pagedSearchByCreaterId(int pageNumber, int pageSize, int createrId, String name){
		String select = "select A.*, \n" +
				"(select B.dic_item_name from t_dictionary B where A.status = B.dic_value) status_des,\n" +
				"(select B.dic_item_name from t_dictionary B where A.type = B.dic_value) type_des";
		String from = "  from t_workflow_model A where creater_id = ? and A.name like concat('%',? ,'%')";
		return Db.paginate(pageNumber, pageSize, select, from, createrId, name);
	}

	/**
	 * 通过流程分类查询已创建工作流模型
	 * @param type 流程模型类型
	 * @param status 流程模型状态 -1|代表全部
	 * @return
	 */
	public List<WorkflowModel> findByType(int type, Integer status) {
		return find("select * from t_workflow_model where type = ? and (status = ? or -1 = ?)", type, status, status);
	}

	private boolean checkBatchResult(int[] resultArray){
		for(int i = 0; i < resultArray.length; i++){
			if(resultArray[i] <= 0){
				return false;
			}
		}
		return true;
	}

	private Result parseWorkflowExtras(JSONObject extras){
		// TODO
		return new Result(false, "未实现");
	}

	private Result parseWorkflowLines(JSONObject lines){
		Iterator<String> iterator = lines.keySet().iterator();
		while (iterator.hasNext()){
			String lineName = iterator.next();
			JSONObject lineJSONObject = lines.getJSONObject(lineName);
			WorknodeModel startNodeModel = serarch(lineJSONObject.getString("from"));
			WorknodeModel endNodeModel = serarch(lineJSONObject.getString("to"));
			String name = lineJSONObject.getString("name").trim();
			int type = Dictionary.LCJDZXJG_TG_16;
			//  进行节点线路校验
			if(startNodeModel == null || endNodeModel == null){
				return new Result(false, name + "连线不合法");
			}
			if(name.equals("拒绝")){
				type = Dictionary.LCJDZXJG_BGT_17;
			}else if(name.equals("弃权")){
				type = Dictionary.LCJDZXJG_QQ_19;
			}

			WorknodeLinkModel worknodeLinkModel = new WorknodeLinkModel();
			worknodeLinkModel.setLineType(type);// TODO 查看type类型
			worknodeLinkModel.setStartNodeModel(startNodeModel);
			worknodeLinkModel.setEndNodeModel(endNodeModel);
			worknodeLinkModelList.add(worknodeLinkModel);
		}
		return new Result(true, "解析工作流连线成功");
	}

	private WorknodeModel serarch(String nodeKey){
		for(WorknodeModel worknodeModel : worknodeModelList){
			if(worknodeModel.getNodeKey().equals(nodeKey)){
				return worknodeModel;
			}
		}
		return null;
	}

	private Result parseWorkflowNodes(JSONObject nodes){
		Iterator<String> nodesKeyIterator = nodes.keySet().iterator();
		String nodeId = "";
		//找到开始节点nodeId
		boolean hasStartNode = false;
		boolean hasEndNode = false;
		Date currentDate = new Date();
		while(nodesKeyIterator.hasNext()){
			boolean isEndNode = false;
			String nodeKey = nodesKeyIterator.next();
			JSONObject nodeJson = nodes.getJSONObject(nodeKey);
			String executoRoleScope = nodeJson.getString("executor_role_scope");
			String notifyRoleScope = nodeJson.getString("notify_role_scope");
			String type = nodeJson.getString("type").trim();
			String name = nodeJson.getString("name").trim();
			int modelType = Dictionary.LCJDZL_ZZJD_29;
			if(type.equals("start round")){
				hasStartNode = true;
				modelType = Dictionary.LCJDZL_KSJD_28;
			}
			if(type.equals("end round")){
				hasEndNode = true;
				isEndNode = true;
				modelType = Dictionary.LCJDZL_JSJD_30;
			}
			WorknodeModel worknodeModel = new WorknodeModel();
			worknodeModel.setNodeKey(nodeKey);
			worknodeModel.setCreateDate(currentDate);
			worknodeModel.setType(modelType);
			worknodeModel.setReviewType(Dictionary.LCJDSHLX_DRDS_31);//默认多人单审
			if(isEndNode == false){
				worknodeModel.setName(name);
				worknodeModel.setExecutorUserScope(",1,");// 默认管理员可以操作所有流程
				worknodeModel.setExecutorRoleScope(","+executoRoleScope+",");
				worknodeModel.setNotifyRoleScop("," + notifyRoleScope + ",");
			}else {
				worknodeModel.setName("结束");
				worknodeModel.setExecutorUserScope("");// 默认管理员可以操作所有流程
				worknodeModel.setExecutorRoleScope("");
				worknodeModel.setNotifyRoleScop("");
			}
			worknodeModelList.add(worknodeModel);
		}
		if(hasStartNode == false){
			return new Result(false, "没有开始节点");
		}
		if(hasEndNode == false){
			return new Result(false, "没有结束节点");
		}
		return new Result(true, "解析工作流节点成功");
	}
	
}
